package archer.application.manager.tag;

import archer.application.manager.service.system.StaffService;
import archer.framework.protocol.result.ExecuteResult;
import archer.framework.utils.ContextUtils;
import archer.framework.utils.MapUtils;
import archer.framework.utils.ValidateUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author kent
 * @date 16/6/28.
 */
public class MenuElTag {

    private static String ID_KEY = "id";
    private static String PARENT_ID_KEY = "parentId";
    private static String CHILDREN_KEY = "children";

    /**
     * 获取菜单
     *
     * @return
     */
    public static List<Map> menuList() {

        return getMenus(SecurityUtils.getSubject());
    }

    private static List<Map> getMenus(Subject subject) {

        List<Map> menus = (List<Map>) subject.getSession().getAttribute("tree-menu");

        if (ValidateUtils.isNotEmpty(menus)) {

            return menus;
        }

        ExecuteResult result = ContextUtils.getBean(StaffService.class).findMyDisplayMenuList();

        if (result.isSuccess() && ValidateUtils.isNotEmpty(result.getResultData())) {

            // 菜单树
            List<Map> menuTree = asTree((List<Map>) result.getResultData());

            // cache it
            subject.getSession(true).setAttribute("tree-menu", menuTree);

            return menuTree;
        }

        return new ArrayList<>();
    }

    /**
     * list 转 tree
     *
     * @param menuList
     * @return
     */
    protected static List<Map> asTree(List<Map> menuList) {

        List<Map> result = new ArrayList<>();

        Map idMap = MapUtils.groupByFields(menuList, ID_KEY);

        for (Map map : menuList) {

            //顶级节点
            if (ValidateUtils.isEmpty(map.get(PARENT_ID_KEY))) {
                result.add(map);
                continue;
            }

            //取父节点
            Map parent = (Map) idMap.get(map.get(PARENT_ID_KEY));
            List children = ValidateUtils.isEmpty(parent.get(CHILDREN_KEY)) ? new ArrayList() : (List) parent.get(CHILDREN_KEY);
            children.add(map);
            parent.put(CHILDREN_KEY, children);
        }
        return result;
    }

}
